/**
 *******************************************************************************
 * @file app_task.c
 * @author .ISS_AUTO (hudandan@issauto.com)
 * @date 2024-09-13  1. Base version;
 *
 * @brief This file for the simple task specification.
 *
 * @copyright Copyright (c) 2024 ISSAUTO TECH Co., Ltd. All rights reserved.
 *
 *******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "app_task.h"

#include "cli_task.h"
#if defined(CAN_MODULE)
    #include "can_task.h"
#endif

/* Exported Function ---------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* PRQA S 3384 ++ */

/*******************************************************************************
 *                                Application
********************************************************************************/

/* CLI USER CODE BEGIN -------------------------------------------------------*/
static void dm_cli_app_handler(unsigned int argc, char *argv[], void *userdata);

/**
 * @brief   CLI表
 */
/*!< 调试指令 */
static const hcli_cmd_t dm_cli_cmds[] = {
    {"@app", "@app help", 1, 6, dm_cli_app_handler},
};

extern void cli_sys_handler(unsigned int argc, char *argv[], void *userdata)
{
    hcli_obj_t *hcli = (hcli_obj_t *)userdata;

    if (argc != 1) return;

    if (strcmp(argv[ARGC_N_IDX_CMD], "help") == 0) {
        hcli->printf(hcli, "\"%s version\\r\\n\"\r\n", hcli->adapt.cli_cmds_list[hcli->cli_index]->name);
        hcli->printf(hcli, "\"%s reset\\r\\n\"\r\n", hcli->adapt.cli_cmds_list[hcli->cli_index]->name);
    } else if (strcmp(argv[ARGC_N_IDX_CMD], "version") == 0) {
        hcli->printf(hcli, "s_ver: %d.%d.%d.%d\r\n",
                     FIRMWARE_REVISION_MAJOR,
                     FIRMWARE_REVISION_MINOR,
                     FIRMWARE_REVISION_REVISION,
                     FIRMWARE_REVISION_BUILD);
        hcli->printf(hcli, "h_ver: %s\r\n", HARDWARE_VERSION);

    } else if (strcmp(argv[ARGC_N_IDX_CMD], "reset") == 0) {
        BKP_DeInit(); /* Clear BKP */

        hcli->printf(hcli, "system reset\r\n");
        STIMER_mDELAY(20);

        User_SystemReset();
    }
}

static void dm_cli_app_handler(unsigned int argc, char *argv[], void *userdata)
{
    hcli_obj_t *hcli = (hcli_obj_t *)userdata;
    char *endPtr;

    cli_sys_handler(argc, argv, userdata);

    if (strcmp(argv[ARGC_N_IDX_CMD], "help") == 0) {
        hcli->printf(hcli, "\"%s printf <num>\\r\\n\"\r\n", hcli->adapt.cli_cmds_list[hcli->cli_index]->name);
        #if (GPIO_DRV_ENABLE)
        hcli->printf(hcli, "\"%s gpio\\r\\n\"\r\n", hcli->adapt.cli_cmds_list[hcli->cli_index]->name);
        #endif
        #if (MONITOR_DRV_ENABLE)
        hcli->printf(hcli, "\"%s adc\\r\\n\"\r\n", hcli->adapt.cli_cmds_list[hcli->cli_index]->name);
        #endif
        hcli->printf(hcli, "\"%s flash <cmd>\\r\\n\"\r\n", hcli->adapt.cli_cmds_list[hcli->cli_index]->name);
    }
    /* Example: @app printf 1 */
    else if (strcmp(argv[ARGC_N_IDX_CMD], "printf") == 0) {
        if (argc == 2) {
            uint32_t debug = (uint32_t)strtol(argv[ARGC_N_IDX_VALUE0], &endPtr, 10);

            if (endPtr != argv[ARGC_N_IDX_VALUE0]) {
                BKP_WriteBkpData(BKP_REG_ID_PRINTF_EN, (debug) ? 1 : 0);
            }

            Project_Global.PRINTF_EN = BKP_ReadBkpData(BKP_REG_ID_PRINTF_EN);
            hcli->printf(hcli, "+printf: %1d\r\n", Project_Global.PRINTF_EN);
        }
    }

    #if (GPIO_DRV_ENABLE)
    /* Example: @app gpio */
    else if (strcmp(argv[ARGC_N_IDX_CMD], "gpio") == 0) {

        if (strcmp(argv[ARGC_N_IDX_VALUE0], "get") == 0) {
            for (size_t i = 0; i < GPIO_DI_CNT_NUM; i++) {
                hcli->printf(hcli, "+DI_%1d: %d\r\n", i, get_gpio_scan_bit(i));
            }
        } else {
            if (argc == 3) {
                uint8_t bit_value = 0xFF;

                if (strcmp(argv[ARGC_N_IDX_VALUE0], "set") == 0) {
                    bit_value = 1;
                } else if (strcmp(argv[ARGC_N_IDX_VALUE0], "rst") == 0) {
                    bit_value = 0;
                }

                if (bit_value != 0xFF) {
                    hcli->printf(hcli, "+%s: %d\r\n", argv[ARGC_N_IDX_VALUE1], bit_value);

                    if (strcmp(argv[ARGC_N_IDX_VALUE1], "A1") == 0) {
                        A1_SET(bit_value);
                    } else if (strcmp(argv[ARGC_N_IDX_VALUE1], "A2") == 0) {
                        A2_SET(bit_value);
                    } else if (strcmp(argv[ARGC_N_IDX_VALUE1], "A3") == 0) {
                        A3_SET(bit_value);
                    } else if (strcmp(argv[ARGC_N_IDX_VALUE1], "A4") == 0) {
                        A4_SET(bit_value);
                    } else if (strcmp(argv[ARGC_N_IDX_VALUE1], "A5") == 0) {
                        A5_SET(bit_value);
                    } else if (strcmp(argv[ARGC_N_IDX_VALUE1], "A6") == 0) {
                        A6_SET(bit_value);
                    } else if (strcmp(argv[ARGC_N_IDX_VALUE1], "H1") == 0) {
                        H1_SET(bit_value);
                    }
                }
            }
        }
    }

    #endif
    #if (MONITOR_DRV_ENABLE)
    /* Example: @app adc */
    else if (strcmp(argv[ARGC_N_IDX_CMD], "adc") == 0) {
        analog_paramInfo_t *pMonitor = Get_Analog_Monitor_Info();

        if (pMonitor != NULL) {
            for (size_t i = 0; i < ADC1_CHAN_NUM; i++) {
                hcli->printf(hcli, "+adc1_%d: %.3f\r\n", i, pMonitor->Cur_Volt1[i]);
            }

            for (size_t i = 0; i < ADC3_CHAN_NUM; i++) {
                hcli->printf(hcli, "+adc3_%d: %.3f\r\n", i, pMonitor->Cur_Volt3[i]);
            }

            hcli->printf(hcli, "+batt: %f\r\n", pMonitor->Battery_Volt);
            hcli->printf(hcli, "+stick: %d %d\r\n", pMonitor->Stick_Value[0], pMonitor->Stick_Value[1]);
        }
    }

    #endif
    /* Example: @app flash default */
    else if (strcmp(argv[ARGC_N_IDX_CMD], "flash") == 0) {
        if (argc == 2) {
            if (strcmp(argv[ARGC_N_IDX_VALUE0], "default") == 0) {
                for (size_t ssm_flash_idx = 0; ssm_flash_idx < SSM_FLASH_ID_MAX_NUM; ssm_flash_idx++) {
                    SSM_Write_Info_Default(ssm_flash_idx);
                }

                hcli->printf(hcli, "@ Reset FLASH...\r\n");

                BKP_DeInit(); /* Clear BKP */
                STIMER_mDELAY(20);
                User_SystemReset();
            }
        }
    }
}

extern hcli_obj_t *app_cli_obj_get(void)
{
    return cli_obj_get();
}

extern void app_dm_cli_cmds_add(hcli_obj_t *p_hcli)
{
    (void)hcli_cmds_add(p_hcli, (hcli_cmd_t *)dm_cli_cmds, sizeof(dm_cli_cmds) / sizeof(hcli_cmd_t));
}

/* CLI USER CODE END   -------------------------------------------------------*/


/* [AK601] USER CODE BEGIN ----------------------------------------------*/

/* [AK601] USER CODE END   ----------------------------------------------*/

/*******************************************************************************
 *                              APP sTask
********************************************************************************/

/**
 * @brief Software/Hardware deinitialization.
 *
 * @param[in] void
 * @return void
 */
void APP_DeInit(void)
{
    /*!< Software/Hardware deinitialization ---------------------------*/
    #if (MONITOR_DRV_ENABLE)
    Analog_Monitor_DeInit();
    #endif

    #if defined(TTL_MODULE)
    Comm_DeInit();
    #endif

    /* [AK601] */
    #if defined(CAN_MODULE)
    uCAN_DeInit();
    #endif

}

/**
 * @brief Software/Hardware Initialization.
 *
 * @param[in] void
 * @return void
 */
void APP_Init(void)
{
    /*!< Software/Hardware initialization ------------------------------*/
    #if (GPIO_DRV_ENABLE)
    user_gpio_driver_init();
    #endif

    #if (MONITOR_DRV_ENABLE)
    Analog_Monitor_Init();
    #endif

    #if defined(TTL_MODULE)
    Comm_Init();
    #endif

    app_dm_cli_cmds_add(cli_obj_get()); //!< Default cli interface

    /* [AK601] */
    #if defined(CAN_MODULE)
    uCAN_Init();
    #endif

    // TBD: ...

}

/**
 * @brief Handle function for Application Driver layer
 *
 * @param[in] arg
 * @return void
 */
void APP_Handle(void *arg)
{
    #if defined(TTL_MODULE)
    Comm_Handle();
    #endif

    #if (GPIO_DRV_ENABLE)
    user_gpio_driver_scan();
    #endif

    #if (MONITOR_DRV_ENABLE)
    Analog_Monitor_Handle();
    #endif


    /* [AK601] */
    #if defined(CAN_MODULE)
    uCAN_Handle();
    #endif

    // TBD: ...


    #if defined(AK601)
    #if (LPM_ENABLE)
    /** @note 当满足特定条件后，对唤醒标志进行清零即可立即进入休眠模式。
     * - 条件1: 上电至少延时2s...
     * - 条件2: ...
     */
    static STimerType App_WorkTimer = 0;

    /*!< 低功耗管理 (At least delay 2s...) */
    if (STIMER_IS_TIMEOUT(App_WorkTimer, 2 * 1000)) {
        // App_WorkTimer = STIMER_GET();

        /* 清除当前唤醒标志 */
        if ((Project_Global.Wake_Flag == BKP_DATA_WKUP_FLAG_WDG)) {
            Project_Global.Wake_Flag = 0; //!< Clear
        }

        /* 清除当前唤醒标志 */
        if ((Project_Global.Wake_Flag == BKP_DATA_WKUP_FLAG_DEFAULT)
                || (Project_Global.Wake_Flag == BKP_DATA_WKUP_FLAG_EXIT_PA0)) {
            hcli_obj_t *p_hcli = app_cli_obj_get();
            p_hcli->printf(p_hcli, "\r\n@ SLEEP(%04X) :B @\r\n", Project_Global.Wake_Flag);

            Project_Global.Wake_Flag = 0; //!< Clear
        }

    }

    #endif
    #endif
}

/**
 * @brief BaseTick Counter
 *
 * @param[in] void
 * @return void
 */
void APP_TimerCallback(void)
{
    /* [AK601] */
    uCAN_TimerCallback();

    // TBD: ...


    #if (GPIO_DRV_ENABLE)
    user_gpio_driver_timer_tick_isr();
    #endif
}

/* PRQA S 3384 -- */
/* END OF FILE ---------------------------------------------------------------*/
